package com.zyx.video.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaInfo;
import ws.schild.jave.MultimediaObject;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;

/**
 * @author Yaxi.Zhang
 * @since 2023/2/19 08:19
 */
@Slf4j
public class VideoFileUtil {

    private static final ImmutableList<String> VIDEO_SUFFIX_LIST = ImmutableList
        .of("mp4", "mov", "avi", "mkv", "m4v", "wmv", "asf", "asx", "rm", "rmvb", "3gp", "dat", "flv", "vob");

    /**
     * 获取视频时长 * @param file 视频文件
     *
     * @return 时长（秒）
     */
    public static int getVideoDuration(MultipartFile file) {
        int duration = 0;
        File tempFile = null;
        try {
            tempFile = File.createTempFile(UUID.fastUUID().toString(false), "." + FileUtil.getSuffix(file.getOriginalFilename()));
            file.transferTo(tempFile);
            MultimediaObject multimediaObject = new MultimediaObject(tempFile);
            MultimediaInfo info = multimediaObject.getInfo();
            duration = (int) Math.ceil((double) info.getDuration() / 1000);
        } catch (Exception e) {
            log.error("获取视频时长失败", e);
        } finally {
            if (tempFile != null) {
                tempFile.delete();
            }
        }
        return duration;
    }

    /**
     * 判断文件是否是视频 * @param file 文件
     *
     * @return 是否是啊视频
     */
    public static boolean isVideo(MultipartFile file) {
        return VIDEO_SUFFIX_LIST.contains(FileUtil.getSuffix(file.getOriginalFilename()));
    }

    public static boolean isVideoFile(File file) {
        return VIDEO_SUFFIX_LIST.contains(FileUtil.getSuffix(file));
    }

    public static String getPathVideoDuration(String path) {
        return getPathVideoDuration(path, null);
    }

    public static String getPathVideoDuration(String path, Function<File, Boolean> cond) {
        AtomicLong al = new AtomicLong();
        FileUtil.walkFiles(Paths.get(path), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                File file = path.toFile();
                MultimediaObject multimediaObject = new MultimediaObject(file);
                try {
                    boolean flag = true;
                    if (Objects.nonNull(cond)) {
                        flag = Objects.equals(Boolean.TRUE, cond.apply(file));
                    }
                    if (isVideoFile(file) && flag) {
                        MultimediaInfo info = multimediaObject.getInfo();
                        al.addAndGet(info.getDuration());
                    }
                } catch (EncoderException e) {
                    e.printStackTrace();
                }
                return super.visitFile(path, attrs);
            }
        });
        return DateUtil.secondToTime((int) (al.get() / 1000));
    }

}
